//  Abstract:
//    See gopsed-detailwindow.h
//
//  Reference:
//    See gopsed-detailwindow.h
//
//  Design Notes:
//    See gopsed-detailwindow.h
//
//  Disclaimer:
//    Copyright (C) 2008, Janice Law <janicel700@gmail.com>.
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
#include <libglademm.h>
#include <gtkmm.h>
#include <boost/shared_ptr.hpp>
#include <boost/tuple/tuple.hpp>
#include "gopsed-detailwindow.h"
#include "opf.h"

using namespace std;
using namespace boost;
using Glib::ustring;
using Glib::RefPtr;

namespace gopsed
{
DetailWindow::DetailWindow(const RefPtr<Gnome::Glade::Xml>& glade_xml)
{
    glade = glade_xml;
    glade->get_widget("dialog1", dialog);
    glade->get_widget("scrolledwindow3", container);
    glade->get_widget("button3", button_add);
    button_add->signal_clicked().connect(sigc::mem_fun(*this, &DetailWindow::on_button_add));
    liststore = Gtk::ListStore::create(columns);
    treeview = new Gtk::TreeView(liststore);
}

Epub::Opf::ustring_1_list DetailWindow::show(Epub::Opf::ustring_1_list param)
{
    Epub::Opf::ustring_1_list result = param;
    Gtk::ListStore::iterator row_it;
    Epub::Opf::ustring_1_list::iterator it;
    for (it = result.begin(); it != result.end(); it++)
    {
        row_it = liststore->append();
        (*row_it)[columns.m_content] = (*it).get<0>();
    }
    treeview->append_column(DetailWindow::AddColumn_control());
    treeview->append_column(DetailWindow::AddColumn_text("Content",
            columns.m_content));
    container->add(*treeview);
    container->show_all();
    int result_val = dialog->run();
    dialog->hide();
    if (result_val == Gtk::RESPONSE_OK)
    {
        result.clear();
        Gtk::TreeNodeChildren childs = treeview->get_model()->children();
        Gtk::TreeIter result_row;
        ustring content;
        for (result_row = childs.begin(); result_row != childs.end(); result_row++)
        {
            content = (*result_row)[columns.m_content];
            result.push_back(Epub::Opf::ustring_1_entry(content));
        }
    }
    container->remove();
    return result;
}

Epub::Opf::ustring_2_list DetailWindow::show(const ustring attrName1,
        Epub::Opf::ustring_2_list param)
{
    Epub::Opf::ustring_2_list result = param;
    Gtk::ListStore::iterator row_it;
    Epub::Opf::ustring_2_list::iterator it;
    for (it = result.begin(); it != result.end(); it++)
    {
        row_it = liststore->append();
        (*row_it)[columns.m_content] = (*it).get<0>();
        (*row_it)[columns.m_attr1] = (*it).get<1>();
    }
    treeview->append_column(DetailWindow::AddColumn_control());
    treeview->append_column(DetailWindow::AddColumn_text("Content",
            columns.m_content));
    treeview->append_column(DetailWindow::AddColumn_text(attrName1,
            columns.m_attr1));
    container->add(*treeview);
    container->show_all();
    int result_val = dialog->run();
    dialog->hide();
    if (result_val == Gtk::RESPONSE_OK)
    {
        result.clear();
        Gtk::TreeNodeChildren childs = treeview->get_model()->children();
        Gtk::TreeIter result_row;
        ustring content, attr1;
        for (result_row = childs.begin(); result_row != childs.end(); result_row++)
        {
            content = (*result_row)[columns.m_content];
            attr1 = (*result_row)[columns.m_attr1];
            result.push_back(Epub::Opf::ustring_2_entry(content, attr1));
        }
    }
    container->remove();
    return result;
}

Epub::Opf::ustring_3_list DetailWindow::show(const ustring attrName1,
        const ustring attrName2, Epub::Opf::ustring_3_list param)
{
    Epub::Opf::ustring_3_list result = param;
    Gtk::ListStore::iterator row_it;
    Epub::Opf::ustring_3_list::iterator it;
    for (it = result.begin(); it != result.end(); it++)
    {
        row_it = liststore->append();
        (*row_it)[columns.m_content] = (*it).get<0>();
        (*row_it)[columns.m_attr1] = (*it).get<1>();
        (*row_it)[columns.m_attr2] = (*it).get<2>();
    }
    treeview->append_column(DetailWindow::AddColumn_control());
    treeview->append_column(DetailWindow::AddColumn_text("Content",
            columns.m_content));
    treeview->append_column(DetailWindow::AddColumn_text(attrName1,
            columns.m_attr1));
    treeview->append_column(DetailWindow::AddColumn_text(attrName2,
            columns.m_attr2));
    container->add(*treeview);
    container->show_all();
    int result_val = dialog->run();
    dialog->hide();
    if (result_val == Gtk::RESPONSE_OK)
    {
        result.clear();
        Gtk::TreeNodeChildren childs = treeview->get_model()->children();
        Gtk::TreeIter result_row;
        ustring content, attr1, attr2;
        for (result_row = childs.begin(); result_row != childs.end(); result_row++)
        {
            content = (*result_row)[columns.m_content];
            attr1 = (*result_row)[columns.m_attr1];
            attr2 = (*result_row)[columns.m_attr2];
            result.push_back(Epub::Opf::ustring_3_entry(content, attr1, attr2));
        }
    }
    container->remove();
    return result;
}

void DetailWindow::on_button_add()
{
    liststore->append();
}

Gtk::TreeViewColumn& DetailWindow::AddColumn_control()
{
    Gtk::CellRendererToggle* toggle_cell = new Gtk::CellRendererToggle;
    Gtk::TreeView::Column* tree_column = new Gtk::TreeView::Column;

    tree_column->set_title("");
    tree_column->pack_start(*toggle_cell);
#ifdef GLIBMM_PROPERTIES_ENABLED
    toggle_cell->property_activatable() = true;
#else
    toggle_cell->set_property("activatable", true);
#endif
    toggle_cell->signal_toggled().connect(sigc::mem_fun(*this, &DetailWindow::on_delete));
    return *tree_column;
}

void DetailWindow::on_delete(const Glib::ustring& path)
{
    liststore->erase(treeview->get_model()->get_iter(path));
}

Gtk::TreeViewColumn& DetailWindow::AddColumn_text(const ustring& title,
        Gtk::TreeModelColumn<Glib::ustring>& column)
{
    Gtk::CellRendererText* text_cell = new Gtk::CellRendererText;
    Gtk::TreeView::Column* tree_column = new Gtk::TreeView::Column;

    tree_column->set_title(title);
    tree_column->pack_start(*text_cell);

    tree_column->set_cell_data_func(*text_cell, sigc::bind(sigc::mem_fun(*this,
            &DetailWindow::on_cell_data_text), column));
#ifdef GLIBMM_PROPERTIES_ENABLED
    text_cell->property_editable() = true;
#else
    text_cell->set_property("editable", true);
#endif
    text_cell->signal_edited().connect(sigc::bind(sigc::mem_fun(*this,
            &DetailWindow::on_edited_text), column));
    return *tree_column;
}

void DetailWindow::on_cell_data_text(Gtk::CellRenderer* renderer,
        const Gtk::TreeModel::iterator& iter,
        Gtk::TreeModelColumn<Glib::ustring>& column)
{
    if (iter)
    {
        Gtk::TreeModel::Row row = *iter;
#ifdef GLIBMM_PROPERTIES_ENABLED
        ((Gtk::CellRendererText*)renderer)->property_text() = row[column];
#else
        ((Gtk::CellRendererText*)renderer)->set_property("text",
                row[column]);
#endif
    }
}

void DetailWindow::on_edited_text(const Glib::ustring& path,
        const Glib::ustring& new_text,
        Gtk::TreeModelColumn<Glib::ustring>& column)
{
    Gtk::TreePath path_obj(path);
    Gtk::TreeModel::iterator iter = treeview->get_model()->get_iter(path);
    if (iter)
    {
        Gtk::TreeModel::Row row = *iter;
        row[column] = new_text;
    }
}
} // gopsed
